"""
pi3diamond example startup script

Please do not modify this file. Instead copy it to a new file -
e.g. named pi3diamond.py - that is not tracked in the repository
and modify it according to your needs.
"""

import logging, logging.handlers
import os
import inspect

path = os.path.dirname(inspect.getfile(inspect.currentframe()))

# First thing we do is start the logger
file_handler = logging.handlers.TimedRotatingFileHandler(path+'/log/diamond_log.txt', 'W6') # start new file every sunday, keeping all the old ones 
file_handler.setFormatter(logging.Formatter("%(asctime)s - %(module)s.%(funcName)s - %(levelname)s - %(message)s"))
file_handler.setLevel(logging.DEBUG)
stream_handler=logging.StreamHandler()
stream_handler.setLevel(logging.INFO) # we don't want the console to be swamped with debug messages
logging.getLogger().addHandler(file_handler)
logging.getLogger().addHandler(stream_handler) # also log to stderr
logging.getLogger().setLevel(logging.DEBUG)
logging.getLogger().info('Starting logger.')

# start the JobManager
from tools import emod
emod.JobManager().start()

# start the CronDaemon
from tools import cron
cron.CronDaemon().start()

# define a shutdown function
from tools.utility import StoppableThread
import threading

def shutdown(timeout=1.0):
    """Terminate all threads."""
    cron.CronDaemon().stop()
    emod.JobManager().stop()
    for t in threading.enumerate():
        if isinstance(t, StoppableThread):
            t.stop(timeout=timeout)

# numerical classes that are used everywhere
import numpy as np 

#########################################
# hardware
#########################################
import hardware.pulse_generator
import hardware.TimeTagger as time_tagger
import hardware.microwave_sources
import hardware.nidaq
import hardware.laser
import hardware.hameg
import hardware.flip_mirror
import hardware.apt_stage
import hardware.power_meter

# create hardware backends
scanner = hardware.nidaq.Scanner(CounterIn='/Dev1/Ctr2',
                                 CounterOut='/Dev1/Ctr3',
                                 TickSource='/Dev1/PFI0',
                                 AOChannels='/Dev1/ao0:2',
                                 TriggerChannels='/Dev1/port0/line0:1',
                                 x_range=(0.,100.),
                                 y_range=(0.,100.),
                                 z_range=(-10.,10.),
                                 )

odmr_counter = hardware.nidaq.PulseTrainCounter(CounterIn='/Dev1/Ctr1',
                                                CounterOut='/Dev1/Ctr0',
                                                TickSource='/Dev1/PFI0'
                                                )

pulse_generator = hardware.pulse_generator.PulseGenerator(serial='XpoJYaysTt', channel_map={'aom':0, 'detect':1, 'sequence':2, 'microwave':3, 'rf':4,})
microwave       = hardware.microwave_sources.SMIQ(visa_address='GPIB0::28')
#microwave_1 = microwave
rf_source       = hardware.microwave_sources.SMIQ(visa_address='GPIB0::30')
laser           = hardware.laser.Laser(voltage_range=(-10.,+10), voltage=-4)
coil            = hardware.hameg.HMP2030Traits('ASRL11::INSTR', voltage_max=24.0, current_max=0.15)
flip_mirror     = hardware.flip_mirror.FlipMirror('/Dev1/port2/line5')
rotation_stage  = hardware.apt_stage.RotationStageTraits(serial='83838311')
#power_meter     = hardware.power_meter.PM100D()


#########################################
# configure hardware
#########################################
pulse_generator.Light()



#########################################
# create measurements
#########################################
import measurements.confocal
import measurements.auto_focus_dim
import measurements.photon_time_trace
import measurements.odmr
import measurements.autocorrelation
import measurements.polarization
import measurements.rabi
import analysis.pulsed

confocal = measurements.confocal.Confocal(scanner)
auto_focus = measurements.auto_focus.AutoFocus(confocal)
time_trace = measurements.photon_time_trace.PhotonTimeTrace(time_tagger)
odmr = measurements.odmr.ODMR(microwave, odmr_counter, pulse_generator)
autocorrelation = measurements.autocorrelation.Autocorrelation(time_tagger)
polarization = measurements.polarization.Polarization(time_tagger, rotation_stage)
rabi_measurement = measurements.rabi.Rabi(pulse_generator,time_tagger,microwave) 
pulsed_tool_tau = analysis.pulsed.PulsedToolTau(measurement=rabi_measurement) 

try:
    auto_focus.load('defaults/auto_focus.pys')
except:
    pass

#########################################
# fire up the GUI
#########################################

# define a panel for laser and mirror hardware controls

from traits.api import HasTraits, Instance
from traitsui.api import View, Item, Group

class HardwarePanel( HasTraits ):
    
    laser   = Instance( hardware.laser.Laser )
    mirror  = Instance( hardware.flip_mirror.FlipMirror )
    stage   = Instance( hardware.apt_stage.RotationStageTraits )
    coil    = Instance( hardware.hameg.HMP2030Traits )
    
    traits_view = View(Group(Item('laser', style='custom', show_label=False),
                             Item('mirror', style='custom', show_label=False),
                             Item('stage', style='custom', show_label=False),
                             Item('coil', style='custom', show_label=False),
                             ),
                       title='Hardware Panel'
                       )
    
hardware_panel = HardwarePanel(laser=laser, mirror=flip_mirror, stage=rotation_stage, coil=coil)
hardware_panel.edit_traits()

confocal.edit_traits()
time_trace.edit_traits()
auto_focus.edit_traits()
odmr.edit_traits()
autocorrelation.edit_traits()
polarization.edit_traits()
pulsed_tool_tau.edit_traits()

